/**
 * @filename RedLockService
 *
 * @module
 *
 * @author Justin <zhou78620051@126.com>
 * @version 1
 * @time 2015/10/15 9:31
 */

var Redis = require("redis");
var Redlock = require('redlock');

var Logger = require('pomelo-logger').getLogger('RedLockService', 'production');

var RedLockConfig = require("../configs/RedLockConfig");

var cluster = [];
var redlock;

function RedLockService() {
  if (!RedLockConfig || !(RedLockConfig.RedisList instanceof Array) || RedLockConfig.RedisList.length <= 0) {
    Logger.warn("RedLock Redis Instance Need At Least 3 And Odd, Current Is [ %s ], " +
      "Please Check Config api/configs/RedLockConfig.js", RedLockConfig.RedisList && RedLockConfig.RedisList.length);
  }

  if (cluster.length == 0) {
    for (var i = 0; i < RedLockConfig.RedisList.length; i++) {
      var host = RedLockConfig.RedisList[i].host;
      var port = RedLockConfig.RedisList[i].port;
      cluster.push(Redis.createClient(port, host));
    }
  }

  if (cluster.length < 3 || cluster.length % 2 != 1) {
    Logger.warn("RedLock Redis Instance Need At Least 3 And Odd, Current Is [ %s ], Please Check Config api/configs/RedLockConfig.js", cluster.length);
  }

  if (!redlock) {
    Logger.debug("RedLock Service init redlock instance");
    redlock = new Redlock(
      // you should have one client for each redis node in your cluster
      cluster, {
        // the expected clock drift; for more details see http://redis.io/topics/distlock
        driftFactor: 0.01,
        // the max number of times Redlock will attempt to lock a resource before erroring
        retryCount: 3,
        // the time in ms between attempts
        retryDelay: 200
      }
    );
  }
  return redlock;
}

module.exports = {
  lock: function (resource, ttl, next) {
    if (typeof ttl == "function") {
      next = ttl;
      ttl = RedLockConfig.ttl || 1000;
    }
    var redLockInstance = new RedLockService();
    redLockInstance.lock(resource, ttl, next);
  }
};
